package com.dong.ch02_array;


import java.util.Arrays;

/**
 * 自定义数组类 : 增删改查
 * data[]
 * capacity
 * size
 */
public class S03_MyArrayEnhance {
    public static void main(String[] args) {
        Array array = new Array(2);
        array.addLast(1);
        array.addLast(2);
        array.addLast(3);
        array.addLast(2);
        array.addLast(2);
        array.addLast(5);
        array.addLast(2);
        array.addFirst(100);
        System.out.println(array);
        array.deleteFirst();
        array.deleteLast();
        array.addFirst(99);
        System.out.println(array);

        array.removeElement(2);
        System.out.println(array);
        array.delete(2);
        System.out.println(array);
        array.removeAllElement(2);
        System.out.println(array);

    }
    public static class Array<E>{
        private static final int INITIAL_SIZE = 8;
        private E[] data;
        private int size;

        public Array(int capacity) {
            if(capacity<0) {
                capacity=INITIAL_SIZE;
            }
            this.data = (E[]) new Object[capacity];
            size=0;
        }

        public Array() {
            this(INITIAL_SIZE);
        }
        public void addFirst(E e) {
            add(0,e);
        }
        public boolean contains(E e) {
            return find(e)>0;
        }
        public int find(E e) {
            for (int i = 0; i < size; i++) {
                if(data[i].equals(e)) {
                    return i;
                }
            }
            return -1;
        }

        /**指定位置插入元素*/
        public void add(int index, E e) {
            verifyIndex(index);
            if(index>getSize()) {
                throw new IllegalArgumentException("数组需要连续");
            }
            if(size==data.length) {
                resize(data.length*2);
            }
            moveElementForward(index);
            data[index]=e;
            size++;
        }
        //数据向后移动
        private void moveElementForward(int startIndex) {
         /*   if(startIndex==0){
                return;
            }*/
            verifyIndex(startIndex);
            for(int i=getSize();i>startIndex;i--) {
                data[i]=data[i-1];
            }
        }
        //数据向前移动
        private void moveElementBackward(int startIndex) {
            verifyIndex(startIndex);
            for(int i = startIndex;i<getSize()-1;i++) {
                data[i]=data[i+1];
            }
        }
        public void addLast(E e) {
            add(size,e);
        }
        private void resize(int targetSize) {
            E[] newData = (E[]) new Object[targetSize];
          /*  for (int i = 0; i < getSize(); i++) {
                newData[i]=data[i];
            }*/
            System.arraycopy(data,0,newData,0,size);

            data=newData;
        }
        public E deleteFirst() {
            return delete(0);
        }
        public E deleteLast() {
            return delete(size-1);
        }

        public E delete(int index) {

            verifyIndex(index);
            E current= data[index];
            if(size==0) {
                throw new IllegalArgumentException("the array is empty now !");
            }
            if(size<getCapacity()/4) {
                resize(getCapacity()/2);
            }
            moveElementBackward(index);
            data[size-1]=null;
            this.size--;
            return current;
        }
        public void update(int index, E value) {
            verifyIndex(index);
            data[index]=value;
        }
        public E get(int index) {
            verifyIndex(index);
            return data[index];
        }
        public int getSize(){
            return size;
        }
        public int getCapacity() {
            return data.length;
        }
        public boolean isEmpty() {
            return size==0;
        }
        public void verifyIndex(int index) {
            if(index>size||index<0) {
                throw new IllegalArgumentException("数组索引位置非法");
            }
        }
        public int removeElement(E e) {
          return removeElement(e,false);
        }
        public int removeAllElement(E e) {
            return removeElement(e,true);
        }
        public int removeElement(E e,boolean removeAll) {
            int num = 0;
            for (int i = 0; i < size; ) {
                if(data[i].equals(e)) {
                    num++;
                    delete(i);
                    if(!removeAll) {
                        return 1;
                    }
                }else {
                    i++;
                }
            }
            return num;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("[ ");
            for (int i = 0; i < this.size-1; i++) {
               sb.append(data[i]).append(',');
            }
            sb.append(data[size-1]).append(" ]");

            return "Array{" +
                    "data=" + sb.toString() +
                    ", size=" + size +
                    ",capacity"+getCapacity()+
                    '}';
        }
    }
}
